import Head from 'next/head';
import TableOptionsTable from '../../../components/prop-tables/TableOptionsTable';
import ColumnOptionsTable from '../../../components/prop-tables/ColumnOptionsTable';
import StateOptionsTable from '../../../components/prop-tables/StateOptionsTable';
import EditingCellExample from '../../../examples/enable-editing-cell';
import EditingModalExample from '../../../examples/enable-editing-modal';
import EditingRowExample from '../../../examples/enable-editing-row';
import EditingTableExample from '../../../examples/enable-editing-table';

<Head>
  <title>Editing Feature Guide - Mantine React Table Docs</title>
  <meta
    name="description"
    content="How to enable data editing features in Mantine React Table"
  />
</Head>

## Editing Feature Guide

If your tables need full CRUD functionality, you can enable editing features in Mantine React Table.

There are 4 visually distinct editing modes to choose from, whether you want to let users [edit data in a modal](#modal-editing-mode), [inline 1 row at a time](#row-editing-mode), [1 cell at a time](#cell-editing-mode), or just always have [editing enabled for every cell](#table-editing-mode).

### Relevant Table Options

<TableOptionsTable
  onlyOptions={
    new Set([
      'createDisplayMode',
      'editDisplayMode',
      'enableEditing',
      'mantineCreateRowModalProps',
      'mantineEditRowModalProps',
      'mantineEditSelectProps',
      'mantineEditTextInputProps',
      'onCreatingRowCancel',
      'onCreatingRowChange',
      'onCreatingRowSave',
      'onEditingCellChange',
      'onEditingRowCancel',
      'onEditingRowChange',
      'onEditingRowSave',
      'renderCreateRowModalContent',
      'renderEditRowModalContent',
    ])
  }
/>

### Relevant Column Options

<ColumnOptionsTable
  onlyOptions={
    new Set([
      'editVariant',
      'enableEditing',
      'mantineEditSelectProps',
      'mantineEditTextInputProps',
    ])
  }
/>

### Relevant State Options

<StateOptionsTable
  onlyOptions={
    new Set(['creatingRow', 'editingCell', 'editingRow', 'isSaving'])
  }
/>

### Enable Editing

To enable editing, first you just need to set the `enableEditing` table option to `true`.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableEditing: true,
});
```

However, this is just the start. You will need to hook up logic and event listeners, but it depends on which editing mode you want to use.

### Editing Modes

Mantine React Table has 4 supported editing modes: `"modal"` (default), `"row"`, `"cell"` and `"table"`. You can specify which editing mode you want to use by passing the `editDisplayMode` prop.

#### Modal Editing Mode

The `"modal"` editing mode opens up a dialog where the user can edit data for 1 row at a time. No data is saved to the table until the user clicks the save button. Clicking the cancel button clears out any changes that were made on that row.

An `onEditingRowSave` callback function prop must be provided where you will get access to the updated row data so that changes can be processed and saved. It is up to you how you handle the data. This function has a `exitEditingMode` parameter that must be called in order to exit editing mode upon save. The reason for this is so that you can perform validation checks before letting the modal close.

> The `onEditingRowSave` callback function prop includes an `exitEditingMode` parameter that must be called in order to exit editing mode upon save. The reason for this is so that you can perform validation checks before letting the modal close.

<EditingModalExample />

#### Row Editing Mode

The `row` editing mode is an inline row editing mode. When edit mode is activated, the row shows the edit components in the data cells. No data is saved to the table until the user clicks the save button. Clicking the cancel button clears out any changes that were made on that row.

You must provide an `onEditingRowSave` callback function prop where you will get access to the updated row data so that changes can be processed and saved. It is up to you how you handle the data. This function has a `exitEditingMode` parameter that must be called in order to exit editing mode upon save. The reason for this is so that you can perform validation checks before letting the modal close.

> The `onEditingRowSave` callback function prop includes an `exitEditingMode` parameter that must be called in order to exit editing mode upon save. The reason for this is so that you can perform validation checks before letting the modal close.

<EditingRowExample />

#### Cell Editing Mode

The `cell` editing mode is a bit simpler visually. Uses double-click cells to activate editing mode, but only for that cell.

Then there is a bit of work for you to do to wire up either the `onBlur`, `onChange`, etc. events yourself in order to save the table data. This can be done in the `mantineEditTextInputProps` table or column option.

<EditingCellExample />

#### Table Editing Mode

The `table` editing mode is similar to the `cell` editing mode, but it simply has all of the data cells in the table become editable all at once.

To save data, you must hook up either the `onBlur`, `onChange`, etc. events yourself. This can be done in the `mantineEditTextInputProps` table or column option.

<EditingTableExample />

### Customizing Editing Components

You can customize both the Editing Modal and the Editing Inputs.

#### Customizing the Editing Modal

You can pass any Mantine Modal Props with the `mantineEditRowModalProps` prop.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableEditing: true,
  mantineEditRowModalProps: {
    closeOnClickOutside: true,
    withCloseButton: true,
  },
});
```

You can also override all the content of the editing modal by passing a `renderEditRowModalContent` prop.

```jsx
const table = useMantineReactTable({
  columns,
  data,
  enableEditing: true,
  renderEditRowModalContent: ({ internalEditComponents, row, table }) => (
    <Stack>
      <Title order={5}>My Custom Edit Modal</Title>
      {internalEditComponents} {/*or map over row.getAllCells() and render your own components */}
      <Flex justify="flex-end">
        <MRT_EditActionButtons row={row} table={table} variant="text" />{' '}
        {/*or render your own buttons */}
      </Flex>
    </Stack>
  ),
});
```

#### Customizing the Editing Inputs

You can pass any Mantine TextInput Props with the `mantineEditTextInputProps` prop.

```jsx
const columns = [
  {
    accessor: 'age',
    header: 'Age',
    mantineEditTextInputProps: {
      required: true,
      variant: 'filled',
    },
  },
];
```

#### Add Validation to Editing Components

You can add validation to the editing components by using the `mantineEditTextInputProps` events. You can write your validation logic and hook it up to either the `onBlur`, `onChange`, etc. events, then set the `error` and `helperText` props accordingly.

If you are implementing validation, you may also need to use the `onEditingRowCancel` prop to clear the validation error state.

```tsx
const [validationErrors, setValidationErrors] = useState({});

const columns = [
  {
    accessor: 'age',
    header: 'Age',
    mantineEditTextInputProps: {
      error: validationErrors.age,
      required: true,
      type: 'number',
      onChange: (event) => {
        const value = event.target.value;
        //validation logic
        if (!value) {
          setValidationErrors((prev) => ({ ...prev, age: 'Age is required' }));
        } else if (value < 18) {
          setValidationErrors({
            ...validationErrors,
            age: 'Age must be 18 or older',
          });
        } else {
          delete validationErrors.age;
          setValidationErrors({ ...validationErrors });
        }
      },
    },
  },
];
```

### Use Custom Editing Components

If you need to use a much more complicated Editing component than the built-in textfield, you can specify a custom editing component with the `Edit` column definition option.

```tsx
const columns = [
  {
    accessorKey: 'email',
    header: 'Email',
    Edit: ({ cell, column, table }) => <Autocomplete />, //see MRT_EditCellTextInput source code for more info
  },
];
```

### Customize Actions/Edit Column

You can customize the actions column in a few different ways in the `displayColumnDefOptions` prop's `'mrt-row-actions'` section.

```jsx
const table = useMantineReactTable({
  data,
  columns,
  displayColumnDefOptions: {
    'mrt-row-actions': {
      header: 'Edit', //change "Actions" to "Edit"
      //use a text button instead of a icon button
      Cell: ({ row, table }) => (
        <Button onClick={() => table.setEditingRow(row)}>Edit Customer</Button>
      ),
    },
  },
});
```
